package pl.gettoknowme.mobile.android.model;

import java.io.IOException;
import java.io.InputStream;
import java.util.UUID;

import pl.gettoknowme.mobile.android.R;
import pl.gettoknowme.mobile.android.util.LoggingUtil;
import android.content.ContentValues;
import android.content.Context;
import android.content.res.Resources;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

/**
 * Klasa wspomagająca zarządzanie wersjami bazy danych
 * @author Michał Kołodziejski
 */
public class DBOpenHelper extends SQLiteOpenHelper {
    
    /**
     * Nazwa bazy danych
     */
    public static final String DB_NAME = "get_to_know_me";
    
    /**
     * Aktualna wersja schematu bazy
     */
    private static final int DB_VERSION = 1;
    
    /**
     * Skrypty SQL
     */
    private static String[] SQL_SCRIPTS;
    
    /**
     * Identyfikatory zasobów ze skryptami SQL
     */
    private static final int[] SQL_SCRIPTS_IDS = {
            R.raw.create_db
        };
    
    /**
     * Kontekst działania
     */
    private Context ctx;
    
    /**
     * Tworzy klasę pomocniczą do zarządzania wersjami bazy danych
     * @param ctx
     */
    public DBOpenHelper(Context ctx) {
        super(ctx, DB_NAME, null, DB_VERSION);
        this.ctx = ctx;
    }
    
    @Override
    public void onCreate(SQLiteDatabase db) {
        LoggingUtil.d(this, "onCreate");
        readSQLScripts(ctx);
        
        executeSQLScript(db, 0);
        createUserSettings(db);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        LoggingUtil.d(this, "onUpgrade");
        readSQLScripts(ctx);
        // uruchomienie skryptów migracyjnych
        for(int i = oldVersion; i < newVersion; ++i){
            executeSQLScript(db, i);
        }
    }

    /**
     * Odczytuje skrypty SQL tworzące i modyfikujące bazę danych
     * @param ctx kontekst działania
     */
    private void readSQLScripts(Context ctx){
        // wczytanie skryptu tworzącego bazę i skryptów migracyjnych
        SQL_SCRIPTS = new String[DB_VERSION];
        
        Resources res = ctx.getResources();
        InputStream is;
        byte[] b;
        
        int i = 0;
        for(int resId : SQL_SCRIPTS_IDS){
            try {
                is = res.openRawResource(resId);
                b = new byte[is.available()];
                is.read(b);
                SQL_SCRIPTS[i++] = new String(b);
            } catch (IOException e) {
                throw new RuntimeException("Unable to read SQL script (i="+i+")", e);
            }
        }
        
    }
    
    /**
     * Wykonuje pojedynczy skrypt SQL. Dzieli go na pojedyncze komendy po czym uruchamia je.
     * @param db uchwyt do bazy danych
     * @param num numer skryptu
     */
    private void executeSQLScript(SQLiteDatabase db, int num){
        String script = SQL_SCRIPTS[num];
        String[] singleStatements = script.split("-- END_OF_STATEMENT");
        
        for(String statement : singleStatements){
            db.execSQL(statement);
        }
    }
    
    /**
     * Tworzy inicjalne ustawienia użytkownika
     * @param db uchwyt do bazy danych
     */
    private void createUserSettings(SQLiteDatabase db){
        String userId = UUID.randomUUID().toString();
        LoggingUtil.d(this, "UUID: "+userId);
        
        ContentValues values = new ContentValues();
        values.put("user_id", userId);
        db.insertOrThrow("user_settings", null, values);
    }
}
